package com.openatc.agent.service.arterial;

import com.openatc.model.model.Feature;
import com.openatc.model.model.Pattern;
import com.openatc.model.model.Phase;
import com.openatc.optimize.fixedtimeplan.config.cross.CrossConfig;
import com.openatc.optimize.fixedtimeplan.config.cross.Ring;
import com.openatc.optimize.fixedtimeplan.model.control.Cross;
import com.openatc.optimize.fixedtimeplan.model.control.FixedtimePlan;
import model.RouteIntsection;
import model.RoutePara;

import java.util.HashMap;
import java.util.List;

/**
 * @author ：panleilei
 * @description
 * @modified By：
 * @version:
 * @date ：Created in 2024/1/23 16:19
 */
public abstract class AbstractArterialTrafficControl implements ArterialTrafficControl {
    /**
     * 计算关键路口的周期
     * @param keyIntersectionId
     * @param devs
     * @return
     */
    protected int calKeyIntersectionCycle(String keyIntersectionId, List<RouteIntsection> devs) {
        return devs.stream().filter(
                dev -> keyIntersectionId.equals(dev.getAgentid())).findFirst().get().getFeature().getPatternList().get(0).getCycle();
    }
    /**
     * 获取协调速度
     * @param routePara
     * @return
     */
    protected double getCoordinationSpeed(RoutePara routePara) {
        // 协调方向
        String type = routePara.getDirection();
        // 上行
        if ("up".equals(type)){
            return routePara.getUpspeed();
        }
        // 下行
        else {
            return routePara.getDownspeed();
        }
    }

    /**
     * 优化各路口周期
     * @param keyCycle
     * @param feature
     */
    protected void cycleopt(int keyCycle, Feature feature) {
        Pattern pattern = feature.getPatternList().get(0);
        List<Phase> phase = feature.getPhaseList();

        CrossConfig crossConfig = new CrossConfig();
        crossConfig.setType("cycle-opt");
        crossConfig.setOptcycle(keyCycle);
        crossConfig.setPattern(pattern);
        crossConfig.setPhaseList(phase);

        crossConfig.init();
        Cross cross = Cross.builder()
                .agentid(crossConfig.getAgentid())
                .crossConfig(crossConfig)
                .phaseMap(new HashMap<>())
                .build();
        cross.updatePhaseMap();

        FixedtimePlan fixedtimePlan = cross.optimize();
        int ringnum = 0;
        for(Ring ring : fixedtimePlan.getRings() ){
            int phasenum = 0;
            for ( Integer id : ring.getSequence() ){
                pattern.getRings().get(ringnum).get(phasenum).setValue((int) cross.getPhaseMap().get(id).getDuration());
                phasenum++;
            }
            ringnum++;
        }
        pattern.setCycle(keyCycle);
    }
}
